package org.yray.sip.wav;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class WavHeader {

    public  static final WavHeader HEADER_WAV=new WavHeader();

    private final char[] fileID = {'R', 'I', 'F', 'F'};
    private int fileLength;
    private char[] wavTag = {'W', 'A', 'V', 'E'};;
    private char[] fmtHdrID = {'f', 'm', 't', ' '};
    private int fmtHdrLeth;
    private short formatTag;
    private short channels;
    private int samplesPerSec;
    private int avgBytesPerSec;
    private short blockAlign;
    private short bitsPerSample;
    private char[] dataHdrID = {'d','a','t','a'};
    private int dataHdrLeth;

    public WavHeader()
    {
        //长度字段 = 内容的大小（PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
        this.fileLength = 0 + (44 - 8);
        this.fmtHdrLeth = 16;
        this.bitsPerSample = 16;
        this.channels = 1;
        this.formatTag = 0x0001;
        this.samplesPerSec = 8000;
        this.blockAlign = (short) (this.channels * this.bitsPerSample / 8);
        this.avgBytesPerSec = this.blockAlign * this.samplesPerSec;
        this.dataHdrLeth = 0;
    }


    public void setDataLen(int dataLen)
    {
        this.fileLength = dataLen + (44 - 8);
        this.dataHdrLeth = dataLen;
    }

    public byte[] getHeaderByte() throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        writeChar(bos, fileID);
        writeInt(bos, fileLength);
        writeChar(bos, wavTag);
        writeChar(bos, fmtHdrID);
        writeInt(bos,fmtHdrLeth);
        writeShort(bos,formatTag);
        writeShort(bos,channels);
        writeInt(bos,samplesPerSec);
        writeInt(bos,avgBytesPerSec);
        writeShort(bos,blockAlign);
        writeShort(bos,bitsPerSample);
        writeChar(bos,dataHdrID);
        writeInt(bos,dataHdrLeth);
        bos.flush();
        byte[] r = bos.toByteArray();
        bos.close();
        return r;
    }

    private void writeShort(ByteArrayOutputStream bos, int s) throws IOException {
        byte[] mybyte = new byte[2];
        mybyte[1] =(byte)( (s << 16) >> 24 );
        mybyte[0] =(byte)( (s << 24) >> 24 );
        bos.write(mybyte);
    }


    private void writeInt(ByteArrayOutputStream bos, int n) throws IOException {
        byte[] buf = new byte[4];
        buf[3] =(byte)( n >> 24 );
        buf[2] =(byte)( (n << 8) >> 24 );
        buf[1] =(byte)( (n << 16) >> 24 );
        buf[0] =(byte)( (n << 24) >> 24 );
        bos.write(buf);
    }

    public static byte[] intToBytes(int n)
    {
        byte[] buf = new byte[4];
        buf[3] =(byte)( n >> 24 );
        buf[2] =(byte)( (n << 8) >> 24 );
        buf[1] =(byte)( (n << 16) >> 24 );
        buf[0] =(byte)( (n << 24) >> 24 );
        return buf;
    }
    private void writeChar(ByteArrayOutputStream bos, char[] id) {
        for (int i=0; i<id.length; i++) {
            char c = id[i];
            bos.write(c);
        }
    }
}


